package com.warren.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.warren.auth.entity.JwtUser;
import com.warren.system.entity.Menu;
import com.warren.system.entity.RoleMenu;
import com.warren.system.mapper.MenuMapper;
import com.warren.system.mapper.RoleMenuMapper;
import com.warren.system.service.MenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.warren.util.RedisUtils;
import org.apache.tomcat.jni.Error;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author warren
 * @since 2021-03-21
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Override
    public List<Menu> getMenuWithRole() {
        return baseMapper.getMenusWithRole();
    }

    @Override
    public List<Menu> getMenusByAdminId() {
        Long adminId = ((JwtUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId();
        //ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        //List<Menu> menus = (List<Menu>) valueOperations.get("menus_" + adminId);
        /*if (CollectionUtils.isEmpty(menus)) {

            valueOperations.set("menus_" + adminId, menus);
        }*/
        List<Menu> menus = baseMapper.getMenusByAdminId(adminId);
        return menus;
    }

    /**
     * 查询所有菜单
     * @return
     */
    @Override
    public List<Menu> getAll() {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        List<Menu> menus = (List<Menu>) redisUtils.get("menus_all");

        if (CollectionUtils.isEmpty(menus)){
            menus = baseMapper.selectList(queryWrapper);
            redisUtils.set("menus_all",menus);
        }
        return menus;
    }

    @Override
    public List<Menu> permsTreeBuild(List<Menu> menus) {
        if (menus.size() == 0){
            //throw new Error("未查询到菜单信息");
        }
        //主菜单
        List<Menu> menuList = new ArrayList<>();
        //子菜单
        List<Menu> subMenusList = new ArrayList<>();
        //具体菜单项
        List<Menu> itemList = new ArrayList<>();
        //权限集合
        List<Menu> permsList = new ArrayList<>();
        //分类菜单的位置
        for (Menu menu : menus) {
            if (menu.getParentId() == 0){
                menuList.add(menu);
            }else if (menu.getParentId() != 0 && menu.getType().equals("0") && (menu.getUrl() == null || menu.getUrl().equals(""))){
                subMenusList.add(menu);
            }else if(menu.getParentId() != 0 && menu.getType().equals("1") && menu.getUrl() != null){
                itemList.add(menu);
            }else if (menu.getParentId() != 0 && menu.getType().equals("2")){
                permsList.add(menu);
            }
        }
        //按钮组合到目录
        for (Menu menu : permsList) {
            findSubMenu(itemList,menu);
        }
        //目录组合到子菜单
        for (Menu menu : itemList){
            findSubMenu(subMenusList,menu);
        }
        //目录组合到主菜单
        for (Menu menu : itemList){
            findSubMenu(menuList,menu);
        }
        //子菜单组合到主菜单
        for (Menu menu : subMenusList){
            findSubMenu(menuList,menu);
        }

        //返回对应菜单树并排序
        if (menuList.size() != 0 && subMenusList.size() != 0){
            sortSubMenu(menuList);
            return menuList;
        }else if (subMenusList.size()!= 0){
            sortSubMenu(subMenusList);
            return subMenusList;
        }else if (itemList.size()!= 0){
            itemList.addAll(menuList);
            sortSubMenu(itemList);
            return itemList;
        }else if (permsList.size() != 0){
            sortSubMenu(permsList);
            return permsList;
        }

        return menuList;
    }

    @Override
    public List<Menu> menuTreeBuild(List<Menu> menus) {
        if(menus.size() == 0){

        }
        //主菜单
        List<Menu> menuList = new ArrayList<>();
        //子菜单
        List<Menu> subMenusList = new ArrayList<>();
        //具体菜单项
        List<Menu> itemList = new ArrayList<>();

        //分类菜单的位置
        for (Menu menu : menus){
            if (menu.getParentId() == 0){
                menuList.add(menu);
            }else if (menu.getParentId() != 0 && menu.getType().equals("0") && (menu.getUrl() == null || menu.getUrl().equals(""))){
                subMenusList.add(menu);
            }else if (menu.getParentId() != 0 && menu.getType().equals("1") && menu.getUrl() != null){
                itemList.add(menu);
            }
        }

        //子菜单组合到主菜单
        for (Menu menu : subMenusList){
            findSubMenu(menuList,menu);
        }

        //具体菜单组合到子菜单
        for (Menu menu : itemList){
            findSubMenu(menuList,menu);
        }

        //排序
        sortSubMenu(menuList);
        return menuList;



    }

    @Override
    public void updateMenu(Menu menu) {
        //menuMapper.deleteById(menu);
        //清除所有菜单redis缓存
        //Set<String> keys = redisUtils.keys("menus_" + "*");
        //redisUtils.sdel(keys);
        menuMapper.updateById(menu);
    }

    @Override
    public void delMenu(Long menuId) {
        menuMapper.deleteById(menuId);
        QueryWrapper<RoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("menu_id",menuId);
        roleMenuMapper.delete(queryWrapper);
        //清除所有菜单redis缓存
        Set<String> keys = redisUtils.keys("menus_" + "*");
        redisUtils.sdel(keys);
    }

    @Override
    public void add(Menu menu) {
        menu.setOpen(0);
        menuMapper.insert(menu);
    }


    /**
     * 递归将子菜单组合到父菜单的children中
     * @param menus
     * @param item
     */
    private void findSubMenu(List<Menu> menus,Menu item){
        for (Menu menu: menus){
            if (item.getParentId().equals(menu.getId())){
                menu.add(item);
            } else if (menu.getChildren().size() > 0) {
                findSubMenu(menu.getChildren(),item);
            }
        }
    }

    /**
     * 递归将children中的数据排序
     * @param menus
     */
    private void sortSubMenu(List<Menu> menus){
        menus.sort(Menu.order());
        for (Menu menu : menus){
            if (menu.getChildren().size() > 0){
                sortSubMenu(menu.getChildren());
            }
        }
    }


}
